package com.acegear.horizon.domain.events.handlers;

import com.acegear.horizon.domain.events.*;
import com.acegear.horizon.domain.models.ClubEvent;
import com.acegear.horizon.domain.models.constraint.ClubEventState;
import com.acegear.horizon.domain.models.constraint.ContentType;
import com.acegear.horizon.domain.models.constraint.FeedType;
import com.acegear.horizon.domain.models.jpa.*;
import com.acegear.horizon.domain.repository.ClubEventRepository;
import com.acegear.horizon.domain.repository.ClubRepository;
import com.acegear.horizon.domain.repository.jpa.ClubEventBaseRepository;
import com.acegear.horizon.domain.repository.jpa.ClubEventItemGroupRepository;
import com.acegear.horizon.domain.repository.jpa.ClubEventQARepository;
import com.acegear.horizon.domain.repository.jpa.ClubEventStageRepository;
import com.acegear.horizon.vendor.ons.ONSConsumer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;

/**
 * Created by wangsike on 2017/1/23.
 */
@Component
public class ClubActivityEventHandler {

    @Autowired
    private ClubEventRepository clubEventRepository;
    @Autowired
    private ClubEventBaseRepository clubEventBaseRepository;
    @Autowired
    private ClubEventStageRepository clubEventStageRepository;
    @Autowired
    private ClubEventItemGroupRepository clubEventItemGroupRepository;
    @Autowired
    private ClubEventQARepository clubEventQARepository;
    @Autowired
    private ClubRepository clubRepository;
    @Autowired
    private ONSConsumer consumer;

    @PostConstruct
    public void newQAEventONS() {
        consumer.consume(NewQAEvent.class, this::newQAEvent);
    }

    @PostConstruct
    public void answerQAEventONS() {
        consumer.consume(AnswerQAEvent.class, this::answerQAEvent);
    }

    @PostConstruct
    public void DeleteQAEventONS() {
        consumer.consume(DeleteQAEvent.class, this::DeleteQAEvent);
    }

    @PostConstruct
    public void clubEventCreateONS() {
        consumer.consume(ActivityCreateEvent.class, this::clubEventCreate);
    }

    @PostConstruct
    public void clubEventModofiedONS() {
        consumer.consume(ActivityModifiedEvent.class, this::clubEventModified);
    }

    @PostConstruct
    public void clubEventDeleteONS() {
        consumer.consume(ActivityDeleteEvent.class, this::clubEventDelete);
    }

    @PostConstruct
    public void clubEventEndONS() {
        consumer.consume(ActivityEndEvent.class, this::clubEventEnd);
    }

    @PostConstruct
    public void clubEventSponsorCreateONS() {
        consumer.consume(ActivitySponsorCreateEvent.class, this::clubEventSponsorCreate);
    }

    @PostConstruct
    public void clubEventSponsorDeleteONS() {
        consumer.consume(ActivitySponsorDeleteEvent.class, this::clubEventSponsorDelete);
    }

    @PostConstruct
    public void clubEventStageCreateONS() {
        consumer.consume(ActivityStageCreateEvent.class, this::clubEventStageCreate);
    }

    @PostConstruct
    public void clubEventStageModifiedONS() {
        consumer.consume(ActivityStageModifiedEvent.class, this::clubEventStageModified);
    }

    @PostConstruct
    public void clubEventStageDeleteONS() {
        consumer.consume(ActivityStageDeleteEvent.class, this::clubEventStageDelete);
    }

    @PostConstruct
    public void clubEventItemDeleteONS() {
        consumer.consume(ActivityGoodsDeleteEvent.class, this::clubEventItemDelete);
    }

    @PostConstruct
    public void clubEventItemModifiedONS() {
        consumer.consume(ActivityGoodsModifiedEvent.class, this::clubEventItemModified);
    }

    @PostConstruct
    public void clubEventItemCreateONS() {
        consumer.consume(ActivityGoodsCreateEvent.class, this::clubEventItemCreate);
    }

    @PostConstruct
    public void clubEventItemGroupDeleteONS() {
        consumer.consume(ActivityGroupDeleteEvent.class, this::clubEventItemGroupDelete);
    }

    @PostConstruct
    public void clubEventItemGroupModifiedONS() {
        consumer.consume(ActivityGroupModifiedEvent.class, this::clubEventItemGroupModified);
    }

    @PostConstruct
    public void clubEventItemGroupCreateONS() {
        consumer.consume(ActivityGroupCreateEvent.class, this::clubEventItemGroupCreate);
    }

    public void newQAEvent(NewQAEvent newQAEvent) {
        if (newQAEvent.getType() == QAType.MANAGEMENT) {
            ClubEventQA clubEventQA = new ClubEventQA(
                    newQAEvent.getEventId(),
                    newQAEvent.getEventQAId(),
                    newQAEvent.getUserId(),
                    newQAEvent.getProblem(),
                    newQAEvent.getAnswer()
            );
            clubEventQARepository.save(clubEventQA);
        }
    }

    public void answerQAEvent(AnswerQAEvent answerQAEvent) {
        Optional<ClubEventQA> qaOptional = clubEventQARepository.findTopByEventQAId(answerQAEvent.getEventQAId());
        qaOptional.ifPresent(clubEventQA1 -> {
            clubEventQA1.setAnswer(answerQAEvent.getAnswer());
            clubEventQA1.setQuestion(answerQAEvent.getProblem());
            clubEventQARepository.save(clubEventQA1);
        });
    }

    @Transactional
    public void DeleteQAEvent(DeleteQAEvent deleteQAEvent) {
        if (deleteQAEvent.getType() == QAType.MANAGEMENT) {
            Optional<ClubEventQA> qaOptional = clubEventQARepository.findTopByEventQAId(deleteQAEvent.getEventQAId());
            if (qaOptional.isPresent()) {
                clubEventQARepository.delete(qaOptional.get());
            }
        }
    }


    public void clubEventCreate(ActivityCreateEvent activityCreateEvent) {
    	System.out.println(activityCreateEvent);

        ClubEventBase clubEventBase = new ClubEventBase(
                activityCreateEvent.getActivityId(),
                activityCreateEvent.getOwnerId(),
                null,
                activityCreateEvent.getName(),
                activityCreateEvent.getStartAt(),
                activityCreateEvent.getEndAt(),
                activityCreateEvent.getSummary(),
                activityCreateEvent.getCover(),
                activityCreateEvent.getServicePhone(),
                activityCreateEvent.getAddress(),
                activityCreateEvent.getLocation(),
                activityCreateEvent.getType(),
                false
        );
        List<ContentPart> contentParts = new ArrayList<>();
        contentParts.add(new ContentPart(ContentType.TEXT, activityCreateEvent.getMemo(), 1));
        ClubEventInfo clubEventInfo = new ClubEventInfo(activityCreateEvent.getActivityId(), contentParts);
        ClubEvent clubEvent = new ClubEvent(clubEventInfo, clubEventBase);
        clubEvent.save();
        //创建活动后，给ClubFeed表里插一条数据
        clubRepository.saveFeed(FeedType.CLUB_EVENT, activityCreateEvent.getOwnerId(), activityCreateEvent.getActivityId());
    }

    @Transactional
    public void clubEventModified(ActivityModifiedEvent activityModifiedEvent) {

        Optional<ClubEvent> clubEvent = clubEventRepository.findByEventId(activityModifiedEvent.getActivityId());

        if (clubEvent.isPresent()) {
            ClubEventBase eventBase = clubEvent.get().getEventBase();
            Optional<ClubEventInfo> clubEventInfo = clubEvent.get().getEventInfo();

            eventBase.setName(activityModifiedEvent.getName());
            eventBase.setType(activityModifiedEvent.getType());
            eventBase.setCover(activityModifiedEvent.getCover());
            eventBase.setEndAt(activityModifiedEvent.getEndAt());
            eventBase.setStartAt(activityModifiedEvent.getStartAt());
            eventBase.setSummary(activityModifiedEvent.getSummary());
            eventBase.setServicePhone(activityModifiedEvent.getServicePhone());
            eventBase.getLocation().update(activityModifiedEvent.getLocation());
            eventBase.getAddress().update(activityModifiedEvent.getAddress());

            if (clubEventInfo.isPresent()) {
                List<ContentPart> contentParts = new ArrayList<>();
                contentParts.add(new ContentPart(ContentType.TEXT, activityModifiedEvent.getMemo(), 1));
                clubEventInfo.get().setIntroduction(contentParts);
                clubEvent.get().setEventInfo(clubEventInfo.get());
            }
            clubEvent.get().save();
        }
    }

    @Transactional
    public void clubEventDelete(ActivityDeleteEvent activityDeleteEvent) {

        Optional<ClubEvent> clubEventOptional = clubEventRepository.findByEventId(activityDeleteEvent.getActivityId());
        if (clubEventOptional.isPresent()) {
            ClubEventBase clubEventBase = clubEventOptional.get().getEventBase();
            if (clubEventBase != null) {
                clubEventBase.setDeleted(true);
                clubEventBaseRepository.save(clubEventBase);
                //删除活动后，ClubFeed表里删除该条数据
                clubRepository.deleteFeed(FeedType.CLUB_EVENT, clubEventBase.getOwnerId(), clubEventBase.getClubEventId());
            }
        }
    }

    public void clubEventEnd(ActivityEndEvent activityEndEvent) {

        Optional<ClubEventBase> clubEventBase = clubEventBaseRepository.findByClubEventId(activityEndEvent.getActivityId());
        if (clubEventBase.isPresent()) {
            clubEventBase.get().setState(ClubEventState.END);
            clubEventBaseRepository.save(clubEventBase.get());
        }
    }

    public void clubEventSponsorCreate(ActivitySponsorCreateEvent activitySponsorCreateEvent) {
        Optional<ClubEventBase> clubEventBase = clubEventBaseRepository.findByClubEventId(activitySponsorCreateEvent.getActivityId());
        if (clubEventBase.isPresent()) {
            List<Long> sponsors = new ArrayList<>();
            if (clubEventBase.get().getSponsors() != null && clubEventBase.get().getSponsors().size() > 0) {
                sponsors = clubEventBase.get().getSponsors();
            }
            sponsors.add(activitySponsorCreateEvent.getClubId());
            clubEventBase.get().setSponsors(sponsors);
            clubEventBaseRepository.save(clubEventBase.get());
//            clubRepository.saveFeed(FeedType.CLUB_EVENT, activitySponsorCreateEvent.getClubId(),
//                    activitySponsorCreateEvent.getActivityId());
        }
    }

    @Transactional
    public void clubEventSponsorDelete(ActivitySponsorDeleteEvent activitySponsorDeleteEvent) {
        Optional<ClubEventBase> clubEventBase = clubEventBaseRepository.findByClubEventId(activitySponsorDeleteEvent.getActivityId());
        if (clubEventBase.isPresent()) {
            if (clubEventBase.get().getSponsors() != null && clubEventBase.get().getSponsors().size() > 0) {
                clubEventBase.get().getSponsors().remove(activitySponsorDeleteEvent.getClubId());
                clubEventBaseRepository.save(clubEventBase.get());
//                clubRepository.deleteFeed(FeedType.CLUB_EVENT, activitySponsorDeleteEvent.getClubId(),
//                        activitySponsorDeleteEvent.getActivityId());
            }
        }
    }

    public void clubEventStageCreate(ActivityStageCreateEvent activityStageCreateEvent) {
        ClubEventStage clubEventStage = new ClubEventStage(
                activityStageCreateEvent.getActivityStageId(),
                activityStageCreateEvent.getActivityId(),
                activityStageCreateEvent.getName(),
                null);
        clubEventStageRepository.save(clubEventStage);
    }

    @Transactional
    public void clubEventStageModified(ActivityStageModifiedEvent activityStageModifiedEvent) {
        Optional<ClubEventStage> clubEventStageOptional = clubEventStageRepository.findByStageIdAndEventId(activityStageModifiedEvent.getActivityStageId(), activityStageModifiedEvent.getActivityId());
        clubEventStageOptional.ifPresent(clubEventStage1 -> {
            clubEventStage1.setStageName(activityStageModifiedEvent.getName());
            clubEventStageRepository.save(clubEventStage1);
        });
    }


    @Transactional
    public void clubEventStageDelete(ActivityStageDeleteEvent activityStageDeleteEvent) {
        Optional<ClubEventStage> clubEventStage = clubEventStageRepository.findByStageIdAndEventId(activityStageDeleteEvent.getActivityStageId(), activityStageDeleteEvent.getActivityId());
        if (clubEventStage.isPresent()) {
            ClubEventStage clubEventStage1 = clubEventStage.get();
            if (clubEventStage1 != null) {
                clubEventStageRepository.delete(clubEventStage1);
            }
        }
    }

    @Transactional
    public void clubEventItemGroupCreate(ActivityGroupCreateEvent activityGroupCreateEvent) {
        ClubEventItemGroup clubEventItemGroup = new ClubEventItemGroup(
                activityGroupCreateEvent.getActivityGroupId(),
                activityGroupCreateEvent.getActivityStageId(),
                activityGroupCreateEvent.getName(),
                activityGroupCreateEvent.getType(),
                null
        );
            Optional<ClubEventStage> clubEventStage = clubEventStageRepository.findByStageId(activityGroupCreateEvent.getActivityStageId());
            if (clubEventStage.isPresent()) {
                ClubEventStage clubEventStage1 = clubEventStage.get();
                List<ClubEventItemGroup> clubEventItemGroups = new ArrayList<>();
                if (clubEventStage1.getItemGroups() != null && clubEventStage1.getItemGroups().size() > 0) {
                    clubEventItemGroups = clubEventStage1.getItemGroups();
                }
                clubEventItemGroups.add(clubEventItemGroup);
                clubEventStage1.setItemGroups(clubEventItemGroups);
                clubEventStageRepository.save(clubEventStage1);
        }
    }

    @Transactional
    public void clubEventItemGroupModified(ActivityGroupModifiedEvent activityGroupModifiedEvent) {

        Optional<ClubEventStage> clubEventStage = clubEventStageRepository.findByStageId(activityGroupModifiedEvent.getActivityStageId());
        if (clubEventStage.isPresent()) {
            List<ClubEventItemGroup> clubEventItemGroups = clubEventStage.get().getItemGroups();
            clubEventItemGroups.forEach((clubEventItemGroups1 -> {
                if (clubEventItemGroups1.getGroupId().equals(activityGroupModifiedEvent.getActivityGroupId())) {
                    clubEventItemGroups1.setGroupName(activityGroupModifiedEvent.getName());
                    clubEventItemGroups1.setGroupType(activityGroupModifiedEvent.getType());
                }
            }));
            clubEventStageRepository.save(clubEventStage.get());
        }
    }

    @Transactional
    public void clubEventItemGroupDelete(ActivityGroupDeleteEvent activityGroupDeleteEvent) {

        ClubEventStage clubEventStage = clubEventStageRepository.findByStageIdAndEventId(activityGroupDeleteEvent.getActivityStageId(), activityGroupDeleteEvent.getActivityId()).get();

        List<ClubEventItemGroup> clubEventItemGroups = clubEventStage.getItemGroups();

        Iterator<ClubEventItemGroup> iterator = clubEventItemGroups.iterator();

        while (iterator.hasNext()) {
            ClubEventItemGroup clubEventItemGroup = iterator.next();
            if (clubEventItemGroup.getGroupId().equals(activityGroupDeleteEvent.getActivityGroupId())) {
                iterator.remove();
                break;
            }
        }
        clubEventStageRepository.save(clubEventStage);
    }

    @Transactional
    public void clubEventItemCreate(ActivityGoodsCreateEvent activityGoodsCreateEvent) {

        ClubEventItem clubEventItem = new ClubEventItem(
                activityGoodsCreateEvent.getActivityGoodsId(),
                activityGoodsCreateEvent.getItemName(),
                activityGoodsCreateEvent.getPrice(),
                activityGoodsCreateEvent.getRestriction(),
                activityGoodsCreateEvent.getInventory()
        );

        ClubEventItemGroup clubEventItemGroupOptional = clubEventItemGroupRepository.findByGroupIdAndStageId(activityGoodsCreateEvent.getActivityGroupId(), activityGoodsCreateEvent.getActivityStageId()).get();

        List<ClubEventItem> clubEventItems = new ArrayList<>();

        if (clubEventItemGroupOptional.getItems() != null && clubEventItemGroupOptional.getItems().size() > 0) {
            clubEventItems = clubEventItemGroupOptional.getItems();
        }
        clubEventItems.add(clubEventItem);
        clubEventItemGroupOptional.setItems(clubEventItems);
        clubEventItemGroupRepository.save(clubEventItemGroupOptional);
    }

    @Transactional
    public void clubEventItemModified(ActivityGoodsModifiedEvent activityGoodsModifiedEvent) {

        Optional<ClubEventItemGroup> clubEventItemGroupOptional = clubEventItemGroupRepository.findByGroupIdAndStageId(activityGoodsModifiedEvent.getActivityGroupId(), activityGoodsModifiedEvent.getActivityStageId());

        clubEventItemGroupOptional.ifPresent(clubEventItemGroup -> {

            List<ClubEventItem> clubEventItemList = clubEventItemGroup.getItems();

            clubEventItemList.stream().forEach((c -> {
                if (c.getItemId().equals(activityGoodsModifiedEvent.getActivityGoodsId())) {
                    c.setPrice(activityGoodsModifiedEvent.getPrice());
                    c.setRestriction(activityGoodsModifiedEvent.getRestriction());
                    c.setInventory(activityGoodsModifiedEvent.getInventory());
                    c.setItemName(activityGoodsModifiedEvent.getItemName());
                }
            }));
            clubEventItemGroupRepository.save(clubEventItemGroupOptional.get());
        });
    }

    @Transactional
    public void clubEventItemDelete(ActivityGoodsDeleteEvent activityGoodsDeleteEvent) {

        Optional<ClubEventItemGroup> clubEventItemGroup = clubEventItemGroupRepository.findByGroupIdAndStageId(activityGoodsDeleteEvent.getActivityGroupId(), activityGoodsDeleteEvent.getActivityStageId());

        clubEventItemGroup.ifPresent(clubEventItemGroup1 -> {

            List<ClubEventItem> clubEventItemList = clubEventItemGroup1.getItems();

            Iterator<ClubEventItem> iterator = clubEventItemList.iterator();

            while (iterator.hasNext()) {
                ClubEventItem clubEventItem = iterator.next();
                if (clubEventItem.getItemId().equals(activityGoodsDeleteEvent.getActivityGoodsId())) {
                    iterator.remove();
                    break;
                }
            }
            clubEventItemGroupRepository.save(clubEventItemGroup.get());
        });
    }
}